import {
  Button,
  Form,
  Input,
  Space,
  Table,
  type FormInstance,
  Dropdown,
  Popover,
  Checkbox,
} from "antd";
import { Component, createRef } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

import { reorder } from "@/utils";

export interface IColumn {
  title: string;
  dataIndex: string;
  search?: boolean; // 用于控制是否在 Form 表单中显示
}

interface IProps {
  columns?: IColumn[];
  request: (parmas: any) => Promise<{ data: any[]; total?: number }>;
}

interface IState {
  loading: boolean;
  dataSource: any[];
  size: string;
  showColumnKeys: string[]; // 要显示的 columnKey 集合 ['id', 'name']
  selfColumns: IColumn[]; // 基于 props.columns 生成的一份自己的 columns
}

export default class ProTable extends Component<IProps, IState> {
  formRef = createRef<FormInstance>();
  current = 1;
  pageSize = 20;

  // 初始化 state
  state: Readonly<IState> = {
    loading: false,
    dataSource: [],
    size: "middle",
    showColumnKeys: this.props.columns?.map((item) => item.dataIndex) || [],
    selfColumns: [...(this.props.columns || [])],
  };

  // 表单查询
  onFinish = (values: any) => {
    // 将表单的values传递给 refresh
    this.refresh(values);
  };

  // 重置
  handleReset = () => {
    this.formRef.current?.resetFields();
    this.refresh();
  };

  // 列设置的 checkbox
  handleCheckbox = (column: IColumn, event: any) => {
    const checked = event.target.checked;
    console.log("handleCheckbox", column, checked);
    // 根据 column.dataIndex 来操作 showColumnKeys
    if (this.state.showColumnKeys.includes(column.dataIndex)) {
      // 存在，则移除
      this.setState((state) => ({
        showColumnKeys: state.showColumnKeys.filter(
          (item) => item !== column.dataIndex
        ),
      }));
    } else {
      // 不存在，则添加
      this.setState((state) => ({
        showColumnKeys: [...state.showColumnKeys, column.dataIndex],
      }));
    }
  };

  // 拖拽结束
  handleEnd = (result: any) => {
    console.log("handleEnd", result);
    // 如果没有 destination 则 放弃
    if (!result.destination) {
      return;
    }

    // 要修改 state.selfColumns 数据
    this.setState({
      selfColumns: reorder(
        this.state.selfColumns,
        result.source.index,
        result.destination.index
      ),
    });
  };

  refresh = async (values?: any) => {
    // 组装 params
    const params = {
      ...values,
      current: this.current,
      pageSize: this.pageSize,
    };
    // loading
    this.setState({ loading: true });
    // 调用 props.request
    const response = await this.props.request(params);
    console.log("获取到的数据为", response.data);
    this.setState({ loading: false, dataSource: response.data });
  };

  render() {
    const {
      state: { dataSource, loading, size, showColumnKeys, selfColumns },
      onFinish,
      handleReset,
      handleCheckbox,
      handleEnd,
    } = this;

    // 基于 state.selfColumns 与 state.showColumnKeys 计算得出给到 Table 使用的 colums
    const tableColumns = selfColumns?.filter((column) =>
      showColumnKeys.includes(column.dataIndex)
    );

    return (
      <Space direction="vertical" style={{ display: "flex" }}>
        <Form ref={this.formRef} layout="inline" onFinish={onFinish}>
          {selfColumns
            ?.filter((item) => item.search !== false)
            .map((column, index) => (
              <Form.Item
                key={index}
                name={column.dataIndex}
                label={column.title}
              >
                <Input />
              </Form.Item>
            ))}
          <Form.Item>
            <Space>
              <Button type="primary" htmlType="submit" loading={loading}>
                查询
              </Button>
              <Button type="dashed" onClick={handleReset}>
                重置
              </Button>
            </Space>
          </Form.Item>
        </Form>

        <hr />

        <Space direction="vertical" style={{ display: "flex" }}>
          <div style={{ display: "flex", justifyContent: "space-between" }}>
            <div>表格工具</div>

            <Space>
              <Button onClick={() => this.refresh()}>刷新</Button>
              <Dropdown
                menu={{
                  items: [
                    { key: "middle", label: "默认" },
                    { key: "small", label: "紧凑" },
                    { key: "large", label: "大的" },
                  ],
                  onClick: ({ key }) => {
                    this.setState({ size: key });
                  },
                }}
              >
                <Button>密度</Button>
              </Dropdown>
              <Popover
                content={
                  <DragDropContext onDragEnd={handleEnd}>
                    <Droppable droppableId="abcd">
                      {(provided) => (
                        <div
                          {...provided.droppableProps}
                          ref={provided.innerRef}
                        >
                          {selfColumns?.map((column, index) => (
                            <Draggable
                              key={column.dataIndex}
                              draggableId={column.dataIndex}
                              index={index}
                            >
                              {(provided) => (
                                <div
                                  ref={provided.innerRef}
                                  {...provided.draggableProps}
                                  {...provided.dragHandleProps}
                                >
                                  <Checkbox
                                    defaultChecked
                                    onChange={(event) =>
                                      handleCheckbox(column, event)
                                    }
                                  >
                                    {column.title}
                                  </Checkbox>
                                </div>
                              )}
                            </Draggable>
                          ))}

                          {provided.placeholder}
                        </div>
                      )}
                    </Droppable>
                  </DragDropContext>
                }
              >
                <Button>设置</Button>
              </Popover>
            </Space>
          </div>

          <hr />

          <Table
            rowKey="id"
            size={size as any}
            loading={loading}
            columns={tableColumns}
            dataSource={dataSource}
          />
        </Space>
      </Space>
    );
  }

  componentDidMount() {
    this.refresh();
  }
}
